﻿namespace Infra.Validation
{
    /// <summary>
    /// Validates a single rule.
    /// </summary>
    /// <typeparam name="T">The object to validate.</typeparam>
    public class SingleRuleValidator<T> : IValidator<T> where T : class
    {
        private ValidationRuleFor<T> StartingRule { get; set; }
      
        public SingleRuleValidator(ValidationRuleFor<T> startingRule)
        {
            this.StartingRule = startingRule;
        }

        /// <summary>
        /// Validates the specified object.
        /// </summary>
        /// <param name="objectToValidate">The object to validate.</param>
        /// <returns></returns>
        public ValidationResult Validate(T objectToValidate)
        {
            var validationResult = new ValidationResult();
            var currentRule = this.StartingRule;

            return ValidateObjectGraph(currentRule, objectToValidate, validationResult);
        }

        /// <summary>
        /// Validates the rule object graph.
        /// </summary>
        /// <param name="currentRule">The current rule.</param>
        /// <param name="objectToValidate">The object to validate.</param>
        /// <param name="validationResult">The validation result.</param>
        /// <returns></returns>
        private ValidationResult ValidateObjectGraph(ValidationRuleFor<T> currentRule, T objectToValidate, ValidationResult validationResult)
        {
            while (currentRule != null)
            {
                currentRule.ValidateWithResult(objectToValidate, validationResult);
                currentRule = currentRule.NextRule;
            }

            return validationResult;
        }
    }
}
